﻿namespace EyeOpen.Crypt.Service.Test
{
    using System;
    using System.Text;
    using EyeOpen.IO;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Test class for EncryptionServiceTest.
    /// </summary>
    [TestClass]
    public class EncryptionServiceTest
    {
        private readonly EncryptionService encryptionService = new EncryptionService();
        private string stringToEncrypt;
        private string password;

        [TestInitialize]
        public void Initialize()
        {
            stringToEncrypt = InitializeStringToEncrypt();
        }

        [TestMethod]
        public void CryptDecryptTestWithSpacesInEncryptionTextExpectedWorks()
        {
            password = "abcdacadasa2a";

            var encryptionResult = encryptionService.CryptDecrypt(password, stringToEncrypt);
            var decryptedText = encryptionService.CryptDecrypt(password, encryptionResult.Text);

            Assert.AreEqual(decryptedText.Text, stringToEncrypt);
        }

        [TestMethod]
        public void CryptDecryptTestWithPasswordSpacesExpectedDecryptedTestIsEqualToClearString()
        {
            password = "abcdabcdaaaaaa a";

            var encryptionResult = encryptionService.CryptDecrypt(password, stringToEncrypt);
            var decryptedText = encryptionService.CryptDecrypt(password, encryptionResult.Text);
            Assert.AreEqual(decryptedText.Text, stringToEncrypt);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CryptDecryptTestWithShortPasswordExpectedException()
        {
            password = "aa";

            var encryptionResult = encryptionService.CryptDecrypt(password, stringToEncrypt);
            var decryptedText = encryptionService.CryptDecrypt(password, encryptionResult.Text);
            Assert.AreEqual(decryptedText.Text, stringToEncrypt);
        }

        [TestMethod]
        public void CryptDecryptTestWithUpperCasePasswordExpectedDecryptedTestIsEqualToClearString()
        {   
            password = "AAAAAAAAAA";

            var encryptionResult = encryptionService.CryptDecrypt(password, stringToEncrypt);
            var decryptedText = encryptionService.CryptDecrypt(password, encryptionResult.Text);

            Assert.AreEqual(decryptedText.Text, stringToEncrypt);
        }

        [TestMethod]
        public void CryptDecryptTestWithUpperCaseStringToEncryptExpectedDecryptedTestIsEqualToClearString()
        {
            password = "abcdabcd";

            var encryptionResult = encryptionService.CryptDecrypt(password, stringToEncrypt);
            var decryptedText = encryptionService.CryptDecrypt(password, encryptionResult.Text);

            Assert.AreEqual(decryptedText.Text, stringToEncrypt);
        }

        [TestMethod]
        public void CryptDecryptTestWithUpperAndLowerCaseStringToEncryptExpectedDecryptedTestIsEqualToClearString()
        {
            password = "abcdabcd";

            var encryptionResult = encryptionService.CryptDecrypt(password, stringToEncrypt);
            var decryptedText = encryptionService.CryptDecrypt(password, encryptionResult.Text);

            Assert.AreEqual(decryptedText.Text, stringToEncrypt);
        }

        private static string InitializeStringToEncrypt()
        {
            var stringtBuilder = new StringBuilder();
            
            const string Encryption = "aaadssssl  d_?11.,èàndsdsdsdsdsdsd\r\n\t\\[";

            for (var i = 0; i < 1000; i++)
            {
                stringtBuilder = stringtBuilder.Insert(stringtBuilder.Length, Encryption);
            }

            return stringtBuilder.ToString();
        }
    }
}